# -*- coding: utf-8 -*-
"""
Module Description: 适配器基类
Date: 2016/12/3
Author:Bai Jin Ping
"""
import framework.distribute.mutex as mutex
from adapter_settings import lock_cfg


class BaseAdapter(object):
    """
    适配器基类

    >>> class ConcreteAdapter(BaseAdapter):
    ...         # __init__() -> 非必要
    ...         # 实现父类抽象方法 -> 必要
    ...         # 新增的功能方法 -> 非必要
    ...         # setter/getter方法 -> 必要
    """

    # 对应的具体模型类
    model_class = None
    # 对应的具体模型查询管理类
    objects = None
    # 标识是否是特殊适配器，目前只有RoleAdapter
    is_special_adapter = False

    def __init__(self, record=None):
        """
        :param record: 对应的具体模型记录
        """
        # 委托的适配对象
        self._record = record

    @classmethod
    def lock(cls, overtime_sec=None, need_lock=True, **kwargs):
        """
        根据当前适配器加锁

        加锁必须传入的字段配置,见pyshare.dal.dal_adapters.adapter_setting.py::lock_cfg
        :param kwargs: 加锁参数 
        :param overtime_sec: 锁超时时间
        :param need_lock: 控制是否真实加锁
        :return: 
        """
        table_name = cls.model_class.__name__
        if len(set(lock_cfg[table_name]) - set(kwargs.keys())) != 0:
            raise KeyError, "LockParameterNotEqual"

        param_list = []
        for key in lock_cfg[table_name]:
            param_list.append(str(kwargs[key]))
        guid = "_".join(param_list)

        adapter_key = "{tablename}:{guid}".format(
            tablename=table_name,
            guid=guid
        )

        return mutex.RMutex(adapter_key, overtime_sec=overtime_sec, need_lock=need_lock)

    def asdict(self):
        """
        转化为字典格式返回
        """
        raise NotImplementedError

    def getJson(self):
        """
        兼容旧的getJson写法
        :return: 
        """
        return self.asdict()

    def save(self):
        """
        保存
        """
        # 该属性为True说明是RoleAdapter，需要更新上下文中的role_data变量
        if self.is_special_adapter:
            from framework.core.context import action_context_storage
            if action_context_storage.ctx.role_data:
                action_context_storage.ctx.role_data = self

        # self.up_model_ver()
        self._record.save()

    def delete(self):
        """
        删除
        """
        # self.up_model_ver()
        # 由于peewee.Model的delete()仅是返回一个DeleteQuery(cls)，而不是通常情况下移除单个记录的方法
        # peewee.Model的delete_instance方法才是用来移除当前记录的方法
        if 'delete_instance' in dir(self._record):
            self._record.delete_instance()
        else:
            self._record.delete()

    # def up_model_ver(self):
    #     """
    #     更新表版本，用于缓存机制
    #     :return:
    #     """
    #     model_name_str = self.model_class.__name__
    #     try:
    #         from pyshare.utils.tb_profile_utils import TbProfileVerManage
    #         TbProfileVerManage.update_table_by_incr_if_table_in_ver_map(model_name_str)
    #     except Exception as e:
    #         import pyshare.framework.runtime_logger as log
    #         error_message = 'up_model_ver run error :  {e}'.format(e=str(e.message))
    #         log.error(error_message, extra={'extra': {'model': model_name_str}})